﻿using System;
using PostSharp.Aspects;
using Sapit.Attributes.Interfaces;

namespace Sapit.PostSharp.Attributes
{
    /// <summary>
    /// Apply this attribute to methods that should be retried.
    /// </summary>
    [Serializable]
    public class RetryAttribute : MethodInterceptionAspect, IRetry
    {
        /// <summary>
        /// Maximum number of times to retry failing method invocations
        /// </summary>
        public int TimesToRetry { get; set; }

        public override void OnInvoke(MethodInterceptionArgs args)
        {
            int numberOfTries = 0;

            while (numberOfTries < TimesToRetry || TimesToRetry == 0)
            {
                numberOfTries += 1;

                try
                {
                    args.Proceed();
                    return;
                }
                catch (Exception)
                {
                    if (numberOfTries == TimesToRetry)
                    {
                        throw;
                    }
                }
            }
        }
    }
}
